package com.leesche.zcsp.node.web.controller.web.v2.device;

import com.leesche.zcsp.node.net.service.NetService;
import com.leesche.zcsp.node.utils.web.PagingResult;
import com.leesche.zcsp.node.utils.web.messge.WebResult;
import com.leesche.zcsp.node.web.controller.web.v2.admin.WebAdminController;
import com.leesche.zcsp.node.web.model.PubDevice;
import com.leesche.zcsp.node.web.model.PubDevicetype;
import com.leesche.zcsp.node.web.model.PubParamGroup;
import com.leesche.zcsp.node.web.service.*;
import com.leesche.zcsp.node.web.service.impl.data.read.*;
import com.leesche.zcsp.node.web.vo.v2.FactoryDeviceListVo;
import com.leesche.zcsp.node.web.vo.v2.FactoryDeviceParamListVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by kaider on 2017/1/7.
 */
@Controller
@RequestMapping("/v2/factory/device")
public class WebFactoryDeviceController extends WebAdminController {

    private final static Logger LOGGER = LoggerFactory.getLogger(WebFactoryDeviceController.class);

    private static final String SHOW_VIEW = "web/v2/device/factory/showView";

    @Autowired
    private PubDevicetypeService deviceTypeService;
    @Autowired
    private PubDeviceService deviceService;
    @Autowired
    private NetService netService;
    @Autowired
    private PubParamGroupService groupService;
    @Autowired
    private PubDevConfigParamService configParamService;
    @Autowired
    private PubDevSetParamService paramService;

    /**
     * 设备模块
     * @param model
     * @return
     */
    @RequestMapping(value = "/showView", method = RequestMethod.GET)
    public String showView(
        QueryPubDeviceTypeCondition condition,
        Model model
    ){
        Long adminId = getFactoryAdminId();
        condition.setAdminId(adminId);
        getDeviceTypeList(condition,model);
        model.addAttribute("view",1);
        return SHOW_VIEW;
    }

    /**
     * 设备类型设备列表
     * @param deviceTypeId
     * @param typeCondition
     * @param deviceCondition
     * @param model
     * @return
     */
    @RequestMapping(value = "/showView/{deviceType}", method = RequestMethod.GET)
    public String showDeviceTypeList(
        @PathVariable("deviceType") Long deviceTypeId,
        QueryPubDeviceTypeCondition typeCondition,
        QueryPubDeviceCondition deviceCondition,
        Model model
    ){
        Long adminId = getFactoryAdminId();
        typeCondition.setAdminId(adminId);
        deviceCondition.setAdminId(adminId);

        getDeviceTypeList(typeCondition,model);
        PubDevicetype deviceType = deviceTypeService.selectByPrimaryKey(deviceTypeId);
        getDeviceList(deviceTypeId,deviceCondition,model);
        model.addAttribute("view",1);
        model.addAttribute("deviceType",deviceTypeId);
        model.addAttribute("deviceTypeName",deviceType.getDtname());
        return SHOW_VIEW;
    }

    /**
     * 设备分页
     * @param typeName
     * @param condition
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/getPagDevice", method = RequestMethod.POST)
    public Map<String,Object> getPagDeviceList(
        Long typeName,
        QueryPubDeviceCondition condition
    ){
        try {
            Long adminId = getFactoryAdminId();
            condition.setAdminId(adminId);
            condition.setDeviceTypeId(typeName);
            PagingResult<FactoryDeviceListVo> scrollResult = deviceService.selectFactoryDeviceListVo(condition);
            return WebResult.success().put("scrollResult",scrollResult).toMap();
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
            return WebResult.failure(e).toMap();
        }
    }

    /**
     * 更新设备类型
     * @param deviceType
     * @param deviceTypeName
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/updateDeviceType", method = RequestMethod.POST)
    public Map<String,Object> updateDeviceType(
            Long deviceType,
            String deviceTypeName
    ){
        try {
            PubDevicetype devicetype = deviceTypeService.selectByPrimaryKey(deviceType);
            devicetype.setDtname(deviceTypeName);
            deviceTypeService.updateByPrimaryKeySelective(devicetype);
            return WebResult.success().toMap();
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
            return WebResult.failure(e).toMap();
        }
    }

    /**
     * 工厂添加设备类型
     * @param typeName
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/addDeviceType", method = RequestMethod.POST)
    public Map<String,Object> addDeviceType(
        String typeName
    ){
        try {
            Long adminId = getFactoryAdminId();
            PubDevicetype deviceType = new PubDevicetype();
            deviceType.setAdminid(adminId);
            deviceType.setDtname(typeName);
            deviceTypeService.insert(deviceType);
            Long deviceTypeId = deviceType.getDevicetypeid();
            return WebResult.success().put("deviceTypeId",deviceTypeId).toMap();
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
            return WebResult.failure(e).toMap();
        }
    }

    /**
     * 更改设备状态
     * @param deviceVal
     * @param stateName
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/updateDeviceState", method = RequestMethod.POST)
    public Map<String,Object> updateDeviceState(
        Long deviceVal,
        Integer stateName
    ){
        try {
            PubDevice device = deviceService.selectByPrimaryKey(deviceVal);
            if(device.getIsonline()!=1){
                return WebResult.failure("设备离线").toMap();
            }
            int deviceTypeId = Integer.parseInt(device.getDevicetypeid().toString());

            netService.sendClientStartOrClose(device.getImme(),deviceTypeId,true);

            device.setState(stateName);
            deviceService.updateByPrimaryKeySelective(device);

            return WebResult.success().toMap();
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
            return WebResult.failure(e).toMap();
        }
    }

    /**
     * 设备的参数列表
     * @param deviceTypeId
     * @param deviceId
     * @param typeCondition
     * @param deviceCondition
     * @param model
     * @return
     */
    @RequestMapping(value = "{deviceType}/showParamView/{device}", method = RequestMethod.GET)
    public String showDeviceParamView(
        @PathVariable("deviceType")Long deviceTypeId,
        @PathVariable("device")Long deviceId,
        QueryPubDeviceTypeCondition typeCondition,
        QueryPubDeviceCondition deviceCondition,
        QueryPubParamGroupCondition groupCondition,
        QueryPubDevSetParamCondition paramCondition,
        Model model
    ){
        Long adminId = getFactoryAdminId();
        typeCondition.setAdminId(adminId);
        deviceCondition.setAdminId(adminId);
        getDeviceTypeList(typeCondition,model);
        groupCondition.setAdminid(adminId);
        groupCondition.setDevicetypeid(deviceTypeId);
        //paramCondition.setAdminId(adminId);
        paramCondition.setDeviceid(deviceId);
        getDeviceParam(groupCondition,paramCondition,model);

        model.addAttribute("view",2);
        model.addAttribute("deviceType",deviceTypeId);
        return SHOW_VIEW;
    }

    /**
     * 获取类型参数组名
     * @param deviceTypeId
     * @param typeCondition
     * @param groupCondition
     * @param model
     * @return
     */
    @RequestMapping(value = "{deviceType}/getParamGroup", method = RequestMethod.GET)
    public String getDeviceParamGroupView(
        @PathVariable("deviceType")Long deviceTypeId,
        QueryPubDeviceTypeCondition typeCondition,
        QueryPubParamGroupCondition groupCondition,
        QueryPubDevConfigParamCondition configParamCondition,
        Model model
    ){
        Long adminId = getFactoryAdminId();
        typeCondition.setAdminId(adminId);
        groupCondition.setAdminid(adminId);
        configParamCondition.setAdminId(adminId);
        configParamCondition.setDeviceTypeId(deviceTypeId);
        groupCondition.setDevicetypeid(deviceTypeId);
        getDeviceTypeList(typeCondition,model);
        getParamGroupList(groupCondition,model);
        PubDevicetype deviceType = deviceTypeService.selectByPrimaryKey(deviceTypeId);
        getConfigParamList(configParamCondition,model);
        model.addAttribute("view",3);
        model.addAttribute("deviceParamType",deviceTypeId);
        model.addAttribute("deviceTypeName",deviceType.getDtname());
        /*model.addAttribute("isOperator",group.getIsoperator());*/
        return SHOW_VIEW;
    }

    /*
    @RequestMapping(value = "{deviceType}/getParamGroup", method = RequestMethod.GET)
    public String getDeviceParamGroupView(
            @PathVariable("deviceType")Long deviceTypeId,
            QueryPubDeviceTypeCondition typeCondition,
            QueryPubParamGroupCondition groupCondition,
            QueryPubDevConfigParamCondition configParamCondition,
            Model model
    ){
        Long adminId = getFactoryAdminId();
        typeCondition.setAdminId(adminId);
        groupCondition.setAdminid(adminId);
        configParamCondition.setAdminId(adminId);
        configParamCondition.setDeviceTypeId(deviceTypeId);
        groupCondition.setDevicetypeid(deviceTypeId);
        getDeviceTypeList(typeCondition,model);
        getParamGroupList(groupCondition,model);
        PubDevicetype deviceType = deviceTypeService.selectByPrimaryKey(deviceTypeId);
        getConfigParamList(configParamCondition,model);
        model.addAttribute("view",3);
        model.addAttribute("deviceParamType",deviceTypeId);
        model.addAttribute("deviceTypeName",deviceType.getDtname());
        return SHOW_VIEW;
    }*/

    /**
     * 参数组
     * @param deviceTypeId
     * @param groupId
     * @param typeCondition
     * @param groupCondition
     * @param configParamCondition
     * @param model
     * @return
     */
    @RequestMapping(value = "{deviceType}/getParamGroup/{groupId}", method = RequestMethod.GET)
    public String getParamView(
        @PathVariable("deviceType")Long deviceTypeId,
        @PathVariable("groupId")Long groupId,
        QueryPubDeviceTypeCondition typeCondition,
        QueryPubParamGroupCondition groupCondition,
        QueryPubDevConfigParamCondition configParamCondition,
        Model model
    ){
        Long adminId = getFactoryAdminId();
        groupCondition.setAdminid(adminId);
        typeCondition.setAdminId(adminId);
        groupCondition.setDevicetypeid(deviceTypeId);
        configParamCondition.setParamgroupid(groupId);
        getDeviceTypeList(typeCondition,model);
        getParamGroupList(groupCondition,model);
        getConfigParamList(configParamCondition,model);
        PubDevicetype deviceType = deviceTypeService.selectByPrimaryKey(deviceTypeId);
        PubParamGroup group = groupService.selectByPrimaryKey(groupId);
        model.addAttribute("view",4);
        model.addAttribute("deviceParamType",deviceTypeId);
        model.addAttribute("deviceTypeName",deviceType.getDtname());
        model.addAttribute("groupId",groupId);
        model.addAttribute("groupName",group.getParamgroupname());
        model.addAttribute("isOperator",group.getIsoperator());
        return SHOW_VIEW;
    }

    /*@RequestMapping(value = "{deviceType}/getParamGroup/{groupId}", method = RequestMethod.GET)
    public String getParamView(
            @PathVariable("deviceType")Long deviceTypeId,
            @PathVariable("groupId")Long groupId,
            QueryPubDeviceTypeCondition typeCondition,
            QueryPubParamGroupCondition groupCondition,
            QueryPubDevConfigParamCondition configParamCondition,
            Model model
    ){
        Long adminId = getFactoryAdminId();
        groupCondition.setAdminid(adminId);
        typeCondition.setAdminId(adminId);
        groupCondition.setDevicetypeid(deviceTypeId);
        configParamCondition.setParamgroupid(groupId);
        getDeviceTypeList(typeCondition,model);
        getParamGroupList(groupCondition,model);
        getConfigParamList(configParamCondition,model);
        PubDevicetype deviceType = deviceTypeService.selectByPrimaryKey(deviceTypeId);
        PubParamGroup group = groupService.selectByPrimaryKey(groupId);
        model.addAttribute("view",4);
        model.addAttribute("deviceParamType",deviceTypeId);
        model.addAttribute("deviceTypeName",deviceType.getDtname());
        model.addAttribute("groupId",groupId);
        model.addAttribute("groupName",group.getParamgroupname());
        return SHOW_VIEW;
    }*/

    /**
     * 查询页面
     * @param model
     * @return
     */
    @RequestMapping(value = "searchView", method = RequestMethod.GET)
    public String searchView(
        QueryPubDeviceTypeCondition condition,
        Model model
    ){
        Long adminId = getFactoryAdminId();
        condition.setAdminId(adminId);
        getDeviceTypeList(condition,model);
        model.addAttribute("view",5);
        return SHOW_VIEW;
    }

    /**
     * 查询设备
     * @param imei
     * @param shortCode
     * @param deviceCondition
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/search", method = RequestMethod.POST)
    public Map<String,Object> search(
        String imei,
        String shortCode,
        QueryPubDeviceCondition deviceCondition
    ){
        try {
            deviceCondition.setImme(imei);
            deviceCondition.setDeviceshortcode(shortCode);
            PubDeviceDto dto = deviceService.selectByCondition(deviceCondition);
            Long deviceName = dto.getDeviceid();
            Long deviceType = dto.getDeviceTypeId();
            return WebResult.success().put("deviceName",deviceName).put("deviceType",deviceType).toMap();
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
            return WebResult.failure(e).toMap();
        }
    }

    /**
     * 获取设备类型列表
     * @param condition
     * @param model
     * @return
     */
    private Model getDeviceTypeList(
        QueryPubDeviceTypeCondition condition,
        Model model
    ){
        List<PubDevicetypeDto> typeList = deviceTypeService.findListsByCondition(condition);
        model.addAttribute("typeList",typeList);
        return model;
    }

    /**
     * 依据不同的设备类型获取设备列表
     * @param deviceTypeId
     * @param condition
     * @param model
     * @return
     */
    private Model getDeviceList(
        Long deviceTypeId,
        QueryPubDeviceCondition condition,
        Model model
    ){
        condition.setDeviceTypeId(deviceTypeId);
        if(condition.getPage()==-10){
            condition.setPage(1);
        }
        PagingResult<FactoryDeviceListVo> scrollResult = deviceService.selectFactoryDeviceListVo(condition);
        model.addAttribute("scrollResult",scrollResult);
        return model;
    }

    /**
     * 设置设备参数
     * @param paramCondition
     * @param model
     * @return
     */
    private Model getDeviceParam(
        QueryPubParamGroupCondition groupCondition,
        QueryPubDevSetParamCondition paramCondition,
        Model model
    ){
        List<FactoryDeviceParamListVo> paramVoList = new ArrayList<FactoryDeviceParamListVo>();
        List<PubParamGroupDto> groupDtoList = groupService.findListsByCondition(groupCondition);
        PubDevicetype deviceType = deviceTypeService.selectByPrimaryKey(groupCondition.getDevicetypeid());
        PubDevice device = deviceService.selectByPrimaryKey(paramCondition.getDeviceid());

        for(PubParamGroupDto groupDto : groupDtoList){
            FactoryDeviceParamListVo vo = new FactoryDeviceParamListVo();
            Long groupId = groupDto.getParamgroupid();
            String groupName = groupDto.getParamgroupname();
            vo.setGroupId(groupId);
            vo.setGroupName(groupName);
            paramCondition.setParamgroupid(groupId);
            List<PubDevSetParamDto> paramList = paramService.findListsByCondition(paramCondition);
            vo.setParamList(paramList);
            paramVoList.add(vo);
        }

        model.addAttribute("typeName",deviceType.getDtname()!=null?deviceType.getDtname():"");
        model.addAttribute("deviceName",device.getDevicename()!=null?device.getDevicename():"");
        model.addAttribute("shortCode",device.getDeviceshortcode()!=null?device.getDeviceshortcode():"");
        model.addAttribute("paramVoList",paramVoList);
        return model;
    }

    /**
     * 获取设备类型参数组
     * @param groupCondition
     * @param model
     * @return
     */
    private Model getParamGroupList(
        QueryPubParamGroupCondition groupCondition,
        Model model
    ){
        List<PubParamGroupDto> groupDtoList = groupService.findListsByCondition(groupCondition);
        model.addAttribute("groupList",groupDtoList);
        return model;
    }

    /**
     * 配置类型组
     * @param configParamCondition
     * @param model
     * @return
     */
    private Model getConfigParamList(
        QueryPubDevConfigParamCondition configParamCondition,
        Model model
    ){
        List<PubDevConfigParamDto> configParamDtoList = configParamService.findListsByCondition(configParamCondition);
        model.addAttribute("configList",configParamDtoList);
        return model;
    }

}
